package models

import (
	"errors"
	"log"
	"time"

	. "xwaf_admin/xadmin/src/lib"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/validation"
	beego "github.com/beego/beego/v2/server/web"
)

// 用户表
type User struct {
	Id            int64
	Sessionid     string    `orm:"size(32)"`
	Username      string    `orm:"unique;size(32)" form:"Username"  valid:"Required;MaxSize(20);MinSize(6)"`
	Password      string    `orm:"size(32)" form:"Password" valid:"Required;MaxSize(20);MinSize(6)"`
	Repassword    string    `orm:"-" form:"Repassword" valid:"Required"`
	Nickname      string    `orm:"unique;size(32)" form:"Nickname" valid:"Required;MaxSize(20);MinSize(2)"`
	Telphone      string    `orm:"unique;size(11)" form:"Telphone" valid:"Required;MaxSize(11);MinSize(11)"`
	Email         string    `orm:"size(32)" form:"Email" valid:"Email"`
	Company       string    `orm:"size(128)" form:"Company"`
	Department    string    `orm:"size(128)" form:"Department"`
	Remark        string    `orm:"null;size(200)" form:"Remark" valid:"MaxSize(200)"`
	Status        int       `orm:"default(1)" form:"Status" valid:"Range(0,1)"`
	Lastlogintime string    `orm:"null;size(255)" form:"-"`
	Lastloginip   string    `orm:"null;size(255)" form:"-"`
	Createtime    time.Time `orm:"type(datetime);auto_now_add" `
	Role          []*Role   `orm:"rel(m2m)"`
}

func (u *User) TableName() string {
	vTable, _ := beego.AppConfig.String("rbac_user_table")
	return vTable
}

func (u *User) Valid(v *validation.Validation) {
	if u.Password != u.Repassword {
		v.SetError("Repassword", "两次输入的密码不一样")
	}
}

// 验证用户信息
func checkUser(u *User) (err error) {
	valid := validation.Validation{}
	b, _ := valid.Valid(&u)
	if !b {
		for _, err := range valid.Errors {
			log.Println(err.Key, err.Message)
			return errors.New(err.Message)
		}
	}
	return nil
}

func init() {
	orm.RegisterModel(new(User))
}

/************************************************************/

// get user list
func Getuserlist(page int64, page_size int64, sort string) (users []orm.Params, count int64) {
	o := orm.NewOrm()
	user := new(User)
	qs := o.QueryTable(user)
	var offset int64
	if page <= 1 {
		offset = 0
	} else {
		offset = (page - 1) * page_size
	}
	qs.Limit(page_size, offset).OrderBy(sort).Values(&users)
	count, _ = qs.Count()
	return users, count
}

// 添加用户
func AddUser(u *User) (int64, error) {
	if err := checkUser(u); err != nil {
		return 0, err
	}
	o := orm.NewOrm()
	user := new(User)
	user.Sessionid = GetRandomString(32)
	user.Username = u.Username
	user.Password = Strtomd5(u.Password)
	user.Nickname = u.Nickname
	user.Telphone = u.Telphone
	user.Email = u.Email
	user.Company = u.Company
	user.Department = u.Department
	user.Remark = u.Remark
	user.Status = u.Status

	id, err := o.Insert(user)
	return id, err
}

// 更新用户
func UpdateUser(u *User) (int64, error) {
	if err := checkUser(u); err != nil {
		return 0, err
	}
	o := orm.NewOrm()
	user := make(orm.Params)
	if len(u.Username) > 0 {
		user["Username"] = u.Username
	}
	if len(u.Nickname) > 0 {
		user["Nickname"] = u.Nickname
	}
	if len(u.Email) > 0 {
		user["Email"] = u.Email
	}
	if len(u.Telphone) > 0 {
		user["Telphone"] = u.Telphone
	}
	if len(u.Company) > 0 {
		user["Company"] = u.Company
	}
	if len(u.Department) > 0 {
		user["Department"] = u.Department
	}
	if len(u.Remark) > 0 {
		user["Remark"] = u.Remark
	}
	if len(u.Password) > 0 {
		user["Password"] = Strtomd5(u.Password)
	}
	if u.Status != 0 {
		user["Status"] = u.Status
	}
	if len(user) == 0 {
		return 0, errors.New("update field is empty")
	}
	var table User
	num, err := o.QueryTable(table).Filter("Id", u.Id).Update(user)
	return num, err
}

func UpdateLoginIpTime(id int64, logintime, loginip string) (int64, error) {
	o := orm.NewOrm()
	user := make(orm.Params)
	user["Lastlogintime"] = logintime
	user["Lastloginip"] = loginip
	var table User
	num, err := o.QueryTable(table).Filter("Id", id).Update(user)
	return num, err
}

func DelUserById(Id int64) (int64, error) {
	o := orm.NewOrm()
	status, err := o.Delete(&User{Id: Id})
	return status, err
}

func GetUserByUsername(username string) (user User, err error) {
	//user = User{Username: username}
	o := orm.NewOrm()
	usert := new(User)
	err = o.QueryTable(usert).Filter("Username", username).Filter("Status", 1).One(&user)
	if err != nil {
		return user, err
	}
	//err = o.Raw("select * from user where status = '2' AND username = ?", username).QueryRow(&user)
	//if err != nil {
	//	return user, err
	//}
	//o.Read(&user, "Username")

	return user, nil
}

// 根据手机获取用户信息
func GetUserByPhoneNo(phoneNo string) (user User, err error) {
	o := orm.NewOrm()
	usert := new(User)
	err = o.QueryTable(usert).Filter("Telphone", phoneNo).Filter("Status", 1).One(&user)
	if err != nil {
		return user, err
	}
	return user, nil
}

func GetUserById(id int64) (user User) {
	user = User{Id: id}
	o := orm.NewOrm()
	o.Read(&user, "Id")
	return user
}

func GetuList() (obj []orm.Params, count int64) {
	o := orm.NewOrm()
	sqlstr := "SELECT username,nickname,department FROM user"
	count, err := o.Raw(sqlstr).Values(&obj)
	if err == nil && count > 0 {
		return obj, count
	}
	return nil, 0
}

// UeditMyInfo完善个人信息
func UeditMyInfo(u *User) (int64, error) {
	if err := checkUser(u); err != nil {
		return 0, err
	}
	o := orm.NewOrm()
	user := make(orm.Params)

	if len(u.Nickname) > 0 {
		user["Nickname"] = u.Nickname
	}
	if len(u.Email) > 0 {
		user["Email"] = u.Email
	}
	if len(u.Telphone) > 0 {
		user["Telphone"] = u.Telphone
	}
	if len(u.Company) > 0 {
		user["Company"] = u.Company
	}
	if len(u.Department) > 0 {
		user["Department"] = u.Department
	}

	if len(user) == 0 {
		return 0, errors.New("update field is empty")
	}
	var table User
	num, err := o.QueryTable(table).Filter("Id", u.Id).Update(user)
	return num, err
}

// 判断pc登录信息,存在用户则更新，不存在则添加
func CheckExitUserOrUpdate(u *User) (User, error) {
	user, err := GetUserByUsername(u.Username)
	if err != nil {
		//return 0,err
		log.Printf("[ERROR] CheckExitUserOrUpdate getuserByUsername Fail:%s\n", err)
	}
	//没有用户就添加
	if user.Id == 0 {
		_, err := AddUser(u) //添加用户
		if err != nil {
			log.Printf("[ERROR] CheckExitUserOrUpdate AddUser Fail:%s\n", err)
			return user, err
		}
		xuser, err2 := GetUserByUsername(u.Username) //插入后查询是否存在用户
		if err != nil {
			log.Printf("[ERROR] CheckExitUserOrUpdate GetUser Fail:%s\n", err2)
			return user, err
		}
		if xuser.Id == 0 {
			return user, errors.New("CheckExitUserOrUpdate GetUserId is 0")
		}
		_, err3 := AddRoleUser(6, xuser.Id) //6的角色ID为只读角色
		if err3 != nil {
			log.Printf("[ERROR] CheckExitUserOrUpdate AddRoleUser Fail:%s\n", err3)
			//return 0, err
		}
		return xuser, nil
	}
	//有用户更新密码
	_, err4 := UpdateUser(u)
	if err4 != nil {
		log.Printf("[ERROR] CheckExitUserOrUpdate UpdateUser Fail:%s\n", err4)
		//return 0, err
	}
	return user, nil
}
